
package com.ttomato.game.mrnom;

import java.util.List;

import android.graphics.Color;

import com.ttomato.game.framework.Game;
import com.ttomato.game.framework.Graphics;
import com.ttomato.game.framework.Pixmap;
import com.ttomato.game.framework.Screen;
import com.ttomato.game.framework.Input.TouchEvent;

public class GameScreen extends Screen {

    enum GameState {
        Ready,
        Running,
        Paused,
        GameOver
    }

    GameState mState = GameState.Ready;

    World mWorld;

    int mOldScore = 0;

    String mSocre = "0";

    public GameScreen(Game game) {
        super(game);
        mWorld = new World();
    }

    @Override
    public void update(float deltaTime) {
        List<TouchEvent> touchEvents = mGame.getInput().getTouchEvents();
        mGame.getInput().getKeyEvents();

        if (mState == GameState.Ready) {
            updateReady(touchEvents);
        }
        if (mState == GameState.Running) {
            updateRunning(touchEvents, deltaTime);
        }
        if (mState == GameState.Paused) {
            updatePaused(touchEvents);
        }
        if (mState == GameState.GameOver) {
            updateGameOver(touchEvents);
        }

    }

    private void updateGameOver(List<TouchEvent> touchEvents) {
        int len = touchEvents.size();
        for (int i = 0; i < len; i++) {
            TouchEvent event = touchEvents.get(i);
            if (event.type == TouchEvent.TOUCH_UP) {
                if (event.x >= 128 && event.x <= 192 &&
                        event.y >= 200 && event.y <= 264) {
                    if (Settings.soundEnabled)
                        Assets.click.play(1);
                    mGame.setScreen(new MainMenuScreen(mGame));
                    return;
                }
            }
        }
    }

    private void updatePaused(List<TouchEvent> touchEvents) {
        int len = touchEvents.size();

        TouchEvent event;

        for (int i = 0; i < len; i++) {
            event = touchEvents.get(i);

            if (event.type == TouchEvent.TOUCH_UP) {
                if (event.x > 80 && event.x <= 240) {
                    if (event.y > 100 && event.y <= 148) {
                        if (Settings.soundEnabled)
                            Assets.click.play(1);
                        mState = GameState.Running;
                        return;
                    }
                    if (event.y > 148 && event.y < 196) {
                        if (Settings.soundEnabled)
                            Assets.click.play(1);
                        mGame.setScreen(new MainMenuScreen(mGame));
                        return;
                    }
                }
            }
        }
    }

    private void updateRunning(List<TouchEvent> touchEvents, float deltaTime) {
        int len = touchEvents.size();
        TouchEvent touchEvent;
        for (int i = 0; i < len; i++) {
            touchEvent = touchEvents.get(i);

            if (touchEvent.type == TouchEvent.TOUCH_UP) {
                if (touchEvent.x < 64 && touchEvent.y < 64) {
                    if (Settings.soundEnabled) {
                        Assets.click.play(1);
                    }
                    mState = GameState.Paused;
                    return;
                }
            }

            if (touchEvent.type == TouchEvent.TOUCH_DOWN) {
                if (touchEvent.x < 64 && touchEvent.y > 416) {
                    mWorld.mSnake.turnLeft();
                }

                if (touchEvent.x > 256 && touchEvent.y > 416) {
                    mWorld.mSnake.turnRight();
                }
            }
        }

        mWorld.update(deltaTime);

        if (mWorld.mGameOver) {
            if (Settings.soundEnabled) {
                Assets.bitten.play(1);
            }
            mState = GameState.GameOver;
        }

        if (mOldScore != mWorld.mScore) {
            mOldScore = mWorld.mScore;
            mSocre = mOldScore + "";
            if (Settings.soundEnabled) {
                Assets.eat.play(1);
            }
        }
    }

    private void updateReady(List<TouchEvent> touchEvents) {
        if (touchEvents.size() > 0) {
            mState = GameState.Running;
        }
    }

    @Override
    public void present(float deltaTime) {
        Graphics graphics = mGame.getGraphics();

        graphics.drawPixmap(Assets.background, 0, 0);

        drawWorld(mWorld);

        if (mState == GameState.Ready) {
            drawReadyUI();
        }
        if (mState == GameState.Running) {
            drawRunningUI();
        }
        if (mState == GameState.Paused) {
            drawPausedUI();
        }
        if (mState == GameState.GameOver) {
            drawGameOverUI();
        }

        drawText(graphics, mSocre, graphics.getWidth() / 2 - mSocre.length() * 20 / 2,
                graphics.getHeight() -
                42);
    }

    private void drawRunningUI() {
        Graphics g = mGame.getGraphics();
        g.drawPixmap(Assets.buttons, 0, 0, 64, 128, 64, 64);
        g.drawLine(0, 416, 480, 416, Color.BLACK);
        g.drawPixmap(Assets.buttons, 0, 416, 64, 64, 64, 64);
        g.drawPixmap(Assets.buttons, 256, 416, 0, 64, 64, 64);
    }

    private void drawPausedUI() {
        Graphics g = mGame.getGraphics();

        g.drawPixmap(Assets.pause, 80, 100);
        g.drawLine(0, 416, 480, 416, Color.BLACK);
    }

    private void drawGameOverUI() {
        Graphics g = mGame.getGraphics();

        g.drawPixmap(Assets.gameOver, 62, 100);
        g.drawPixmap(Assets.buttons, 128, 200, 0, 128, 64, 64);
        g.drawLine(0, 416, 480, 416, Color.BLACK);
    }

    private void drawReadyUI() {
        Graphics g = mGame.getGraphics();

        g.drawPixmap(Assets.ready, 47, 100);
        g.drawLine(0, 416, 480, 416, Color.BLACK);

    }

    private void drawWorld(World world) {
        Graphics graphics = mGame.getGraphics();
        Snake snake = world.mSnake;
        SnakePart head = snake.mParts.get(0);
        Stain stain = world.mStain;

        Pixmap stainPixmap = null;
        switch (stain.mType) {
            case Stain.TYPE_1:
                stainPixmap = Assets.stain1;
                break;
            case Stain.TYPE_2:
                stainPixmap = Assets.stain2;
                break;
            case Stain.TYPE_3:
                stainPixmap = Assets.stain3;
                break;
            default:
                stainPixmap = Assets.stain1;
                break;
        }
        graphics.drawPixmap(stainPixmap, stain.mX * 32, stain.mY * 32);

        int x;
        int y;

        int len = snake.mParts.size();
        for (int i = 1; i < len; i++) {
            SnakePart part = snake.mParts.get(i);
            x = part.mX * 32;
            y = part.mY * 32;
            graphics.drawPixmap(Assets.tail, x, y);
        }
        Pixmap headPixmap = null;
        if (snake.mDirection == Snake.UP)
            headPixmap = Assets.headUp;
        if (snake.mDirection == Snake.LEFT)
            headPixmap = Assets.headLeft;
        if (snake.mDirection == Snake.DOWN)
            headPixmap = Assets.headDown;
        if (snake.mDirection == Snake.RIGHT)
            headPixmap = Assets.headRight;
        x = head.mX * 32 + 16;
        y = head.mY * 32 + 16;
        graphics.drawPixmap(headPixmap, x - headPixmap.getWidth() / 2, y -
                headPixmap.getHeight() / 2);
    }

    public void drawText(Graphics g, String line, int x, int y) {
        int len = line.length();
        for (int i = 0; i < len; i++) {
            char character = line.charAt(i);
            if (character == ' ') {
                x += 20;
                continue;
            }
            int srcX = 0;
            int srcWidth = 0;
            if (character == '.') {
                srcX = 200;
                srcWidth = 10;
            } else {
                srcX = (character - '0') * 20;
                srcWidth = 20;
            }
            g.drawPixmap(Assets.numbers, x, y, srcX, 0, srcWidth, 32);
            x += srcWidth;
        }
    }

    @Override
    public void pause() {
        if (mState == GameState.Running) {
            mState = GameState.Paused;
        }

        if (mWorld.mGameOver) {
            Settings.addScore(mOldScore);
            Settings.save(mGame.getFileIO());
        }
    }

    @Override
    public void resume() {
        // TODO Auto-generated method stub

    }

    @Override
    public void dispose() {
        // TODO Auto-generated method stub

    }

}
